import { AnyAction, Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { fetchValidation } from '@/utils';
import {
  queryTookManagementReceipt,
  queryTookManagementSendCount,
  queryTookManagementSendStatus,
  queryTookManagemenPrintOutbox,
} from './service';

export type Effect = (
  action: AnyAction,
  effects: EffectsCommandMap & { select: <T>(func: (state: {}) => T) => T },
) => void;

export interface ModelType {
  namespace: string;
  state: {};
  effects: {
    fetch: Effect;
    sendingCount: Effect;
    sendingStatus: Effect;
    printOutbox: Effect;
  };
  reducers: {
    save: Reducer;
    clear: Reducer;
    changeModal: Reducer;
  };
}

const stateInfo = {
  dataInfo: {
    count: 0,
    list: [],
  },
  statusList: {},
  countInfo: {},
  outboxInfo: {},
  printVisible: false,
};

const Model: ModelType = {
  namespace: 'tookManagementReceipt',

  state: stateInfo,

  effects: {
    * fetch({ payload }, { call, put }) {
      const response = yield call(queryTookManagementReceipt, payload);
      const data = fetchValidation(response);
      yield data && put({
        type: 'save',
        payload: {
          type: 'dataInfo',
          data: data.body,
        },
      });
    },

    * sendingCount({ payload }, { call, put }) {
      const response = yield call(queryTookManagementSendCount, payload);
      const data = fetchValidation(response);
      yield data && put({
        type: 'save',
        payload: {
          type: 'countInfo',
          data: data.body,
        },
      });
    },

    * sendingStatus({ payload }, { call, put }) {
      const response = yield call(queryTookManagementSendStatus, payload);
      const data = fetchValidation(response);
      yield data && put({
        type: 'save',
        payload: {
          type: 'statusList',
          data: data.body,
        },
      });
    },

    * printOutbox({ payload }, { call, put }) {
      const { logisName, expressName, ...query } = payload;
      const response = yield call(queryTookManagemenPrintOutbox, query);
      const data = fetchValidation(response);
      if (data && data.body) {
        const { body } = data;
        const params = {
          logisName,
          expressName,
          outTime: query.startTime,
          data: body,
        };
        yield put({
          type: 'save',
          payload: {
            type: 'outboxInfo',
            data: params,
          },
        });
        yield put({
          type: 'save',
          payload: {
            type: 'printVisible',
            data: !!body,
          },
        });
      }
    },
  },

  reducers: {
    save(state, { payload }) {
      return {
        ...state,
        [payload.type]: payload.data,
      };
    },

    clear() {
      return stateInfo;
    },

    changeModal(state, { payload }) {
      return {
        ...state,
        printVisible: payload,
      };
    },
  },
};

export default Model;
